/**
 ********************************************************************************************************
 * @file           main.c
 * @author         Dingzhenghao
 * @brief          主函数文件
 * MCU:            CMS8S6990
 ********************************************************************************************************
  */
/****************************************************************************/
/*	include files
*****************************************************************************/
#include "cms8s6990.h"
#include "Temp_Control.h"
#include "stdio.h"

/****************************************************************************/
/*	Local pre-processor symbols('#define')
*****************************************************************************/

/****************************************************************************/
/*	Global variable definitions(declared in header file with 'extern')
*****************************************************************************/


/****************************************************************************/
/*	Local type definitions('typedef')
*****************************************************************************/

/****************************************************************************/
/*	Local variable  definitions('static')
*****************************************************************************/
int8_t  	i;																		                        /* 计数值i  	         			*/
int16_t		GusSvValue = 0;															                        /* SV值			         			*/
int16_t		GusPvValue = 0;															                        /* PV值			         			*/
int8_t  	GcSvNixieBuf[4] = {0,0,0,0};											                        /* SV数码管缓存数组      			*/
int8_t 		GcPvNixieBuf[4] = {0,0,0,0};											                        /* PV数码管缓存数组      			*/
uint8_t		GucKeyNum = 0;															                        /* 键值全局变量          			*/
uint8_t		GucSvSetSelect = 0;														                        /* SV闪烁选择位          			*/
uint8_t		GucSvSetFlashFlag = 0;													                        /* SV闪烁标志位          			*/
xdata uint16_t 	GusADC_Result = 0;															                /* 按键读取ADC值         			*/
MODE_ENUM 	MODE = 0;																                        /* 显示菜单模式          			*/
xdata uint8_t 	GucMainMenuIndex = 0;													                    /* 主菜单显示索引        			*/
xdata uint8_t 	GucCountMenu = 0;															                /* 主菜单无操作返回计数值			*/
xdata int16_t 	GusMainMenuBuf[MAIN_TABLE_MAX] = {100, 10, 110, 0, 30, 2, 120, 30, 80, 20, 0, 0,			/* 主菜单缓存数组 		 			*/
									   0, -40, 999, 2, 2, 50,610};											/* 工程师菜单缓存数组 	 			*/
xdata uint8_t 	GucSvValueSign = 0;																			/* SV_Value为负 		 			*/
xdata uint8_t 	GucBackFlag = 0;																			/* 返回标志位	 		 			*/
xdata uint8_t 	GucPvSetADC_Flag = 0;																		/* PVadc刷新标志位	 	 			*/
xdata uint8_t 	GucPvSetATU_Flag = 0;																		/* AT整定周期标志位	 	 			*/
xdata float 	GsTemperature = 0;																			/* 摄氏度变量		 	 			*/
xdata uint8_t	GsPvShowmode = 0;																			/* SV显示模式，0为摄氏度，1为华氏度 */
xdata uint8_t	GsLongKeyState = 0;																			/* 按键长按状态					    */
//xdata uint8_t	PID_Calculate_flag = 1;																		/* PID计算标志位 */
xdata uint8_t	GsTempError = 0;																			/* 温度输入错误标志位 */
xdata float		Gusvoltage = 0;																				/* 温度输入错误标志位 */
xdata uint16_t	GusZeroPointVoltage = 610;																	/* 零点电压			 */
//xdata uint16_t	GusTempBuf_DATA_Flash[225] = {0};
//u16 Voltage = 0;																							/* 热电偶两端电压，放大1000倍 */
/****************************************************************************/
/*	Local function prototypes('static')
*****************************************************************************/
/* 硬件外设初始化 */
static void Hardware_Init(void)
{
	TMR0_Config();													/* 定时器0，用于扫描按键和数码管 */
	TMR1_Config();													/* 用于延时 */
	GPIO_Init();
	key_Init();
//	UART0_Config();
}

/* 开机动画显示 */
static void BootShow(void)
{
	Nixie_SetBuf(2,  1);
	Nixie_SetBuf(3, 12);
	Nixie_SetBuf(4, 13);
	Nixie_SetBuf(5, 14);
	Nixie_SetBuf(6, 15);
	Nixie_SetBuf(7, 10);
	Nixie_SetBuf(8, 16);
	Nixie_SetBuf_forcase9(0, 0);
	delay_ms(1000);
	GusSvValue = -50;
	GusPvValue = 999;
	SvNixieBuf_Set(GcSvNixieBuf, GusSvValue);
	PvNixieBuf_Set(GcPvNixieBuf, GusPvValue);
	Nixie_Show(SV);
	Nixie_Show(PV);
	delay_ms(1000);
}

/* 读取flash数据到菜单缓存数组 */
static void ReadMenuFlash(void)
{
	for(i = 0; i < MAIN_TABLE_MAX; i ++)
	{
		GusMainMenuBuf[i] = FLASH_ReadHalfWord(FLASH_LAST_PAGE + i * 2);
		delay_ms(5);
	}
//	GusZeroPointVoltage = POINTVOTAGE;
}

//static void Read_GusTempBuf(void)
//{
////	if()
//	for(i = 0; i < 225; i ++)
//	{
//		GusTempBuf_DATA_Flash[i] = FLASH_ReadHalfWord(i * 2);
//	}
//}

/* COD=999复位函数，即将所有参数值设为默认值 */
static void MenuFlash_Init(void)
{
	SV_MENU	 = 100;
	AL1		 = 10;
	AL2		 = 60;
	AT		 = 0;
	PID_P		 = 18;
	OH		 = 2;
	PID_I		 = 33;
	PID_D		 = 3;
	Ar		 = 80;
	T		 = 20;
	SC		 = 0;
	LCK		 = 0;
	COD 	 = 0;
	SLL		 = -50;
	SLH		 = 999;
	AH1		 = 2;
	AH2		 = 2;
	DF		 = 50;
	POINTVOTAGE = 610;
	FLASH_WritePage(FLASH_LAST_PAGE, GusMainMenuBuf);							/* 写入flash最后一页					 								*/
}
/****************************************************************************/
/*	Function implementation - global ('extern') and local('static')
*****************************************************************************/

/*****************************************************************************
 ** \brief	 main
 **
 ** \param [in]  none
 **
 ** \return 0
 *****************************************************************************/
int main(void)
{
	delay_ms(500);
	Hardware_Init();															/* 硬件初始化					 										*/
	BootShow();																	/* 开机界面						 										*/
	ReadMenuFlash();															/* 从flash中读取设置值到菜单数组 										*/
	GusSvValue = SV_MENU;                                         				/* 开机需显示SV参数值			 										*/
	
//	GusADC_Result = middleValueFilter();
//	GsTemperature = (int16_t)temp_Sample(GusADC_Result);
//	temperature_limiting();
//	GusPvValue = (uint16_t)GsTemperature;
	
	SvNixieBuf_Set(GcSvNixieBuf, GusSvValue);									/* 设置SV显示数组的值 			 										*/
	PvNixieBuf_Set(GcPvNixieBuf, GusPvValue);									/* 设置PV显示数组的值 			 										*/
	PID_Init();
//	Nixie_SetBuf(1, 8);
//	Nixie_SetBuf(2, 8);
//	Nixie_SetBuf(3, 8);
//	Nixie_SetBuf(4, 8);
//	Nixie_SetBuf(5, 8);
//	Nixie_SetBuf(6, 8);
//	Nixie_SetBuf(7, 8);
//	Nixie_SetBuf(8, 8);
//	Nixie_SetBuf_forcase9(1, FANRENHEIT	);
//	Nixie_SetBuf_forcase9(1, CENTIGRADE	);
//	Nixie_SetBuf_forcase9(1, ALM1		);
//	Nixie_SetBuf_forcase9(1, ALM2		);
//	Nixie_SetBuf_forcase9(1, OUT		);
//	Nixie_SetBuf_forcase9(1, AT_S		);
	
	while(1)
	{
		
		key_handle();															/* 按键处理函数  				 										*/
		GucKeyNum = key_GetNum();												/* 获取键值						 										*/
		key_DoubleLongState();
		
//		/* 串口调PID时使用代码，串口用P23,P22 */
////		GusADC_Result = middleValueFilter();
////		GsTemperature = temp_Sample(GusADC_Result);
////		GusPvValue = (uint16_t)GsTemperature;
//		if(GucPvSetADC_Flag == 1)
//		{
//			GusADC_Result = middleValueFilter();
//			GsTemperature = temp_Sample(GusADC_Result);
//			Gusvoltage = ((float)GusADC_Result/4095)*5;
//			GusPvValue = GsTemperature;
//			GucPvSetADC_Flag = 0;
//			
////			if(PID_Auto_Deal == 1)
////			{
////				pid.Pv = GsTemperature;
////				PID_Auto();
////			}
//			
//			
//			
////			printf("%d\n", GusPvValue);
//			printf("Gusvoltage = %.3f\r\n", Gusvoltage);
////			printf("%.2f, %.2f, %.2f\n",pid.Kp,pid.Ki,pid.Kd);
////			printf("%d, %d, %.2f, %d, %.2f\n", GusADC_Result, 669, GsTemperature, pid.Sv, pid.PID_OUT);
////			printf("%d, %.2f\n", GusADC_Result, (float)GusPvValue);
//		}
//		PvNixieBuf_Set(GcPvNixieBuf, GusPvValue);
//		Nixie_Show(PV);
////		pid.Pv = GusPvValue;
////		PvNixieBuf_Set(GcPvNixieBuf, GusPvValue);
////		Nixie_Show(PV);
////		
//		GusSvValue = (uint8_t)pid.Kp;
//		SV_MENU = pid.Sv;
//		SvNixieBuf_Set(GcSvNixieBuf, GusSvValue);
//		Nixie_Show(SV);
//		
//		/********************************/
		
		if(GucBackFlag == 1)
		{
			if(COD == 999)														/* COD = 999,系统复位，即所有参数恢复默认								 */
			{
				MenuFlash_Init();
				SetSvNixieBuf(INDEX_SV_MENU);									/* 将主菜单缓存数组值写入SV显示缓存数组，即在显示数组写入SV				 */
				MODE = MODE_SV_SHOW;											/* 返回开始界面	   														 */
				COD = 0;														/* COD清零																 */
			}
			else if(COD == 10)
			{
				POINTVOTAGE = ((float)middleValueFilter()/4095)*5*1000;			/* 零点电压校准 */
//				FLASH_WritePage(FLASH_LAST_PAGE, GusMainMenuBuf);							/* 将设置数据写入FLASH			 	 					 */
				SetSvNixieBuf(INDEX_SV_MENU);									/* 将主菜单缓存数组值写入SV显示缓存数组，即在显示数组写入SV				 */
				MODE = MODE_SV_SHOW;											/* 返回开始界面	   														 */
				COD = 0;														/* COD清零																 */
			}
			parametric_limiting();
			/* 写入FLASH保存 */
			FLASH_WritePage(FLASH_LAST_PAGE, GusMainMenuBuf);							/* 将设置数据写入FLASH			 	 					 */
			/*****************/
			MODE = MODE_SV_SHOW;												/* 跳回开始界面						 									*/
			SetSvNixieBuf(INDEX_SV_MENU);										/* 显示缓存数组中写入SV参数值		 									*/
			PID_Save();
			GucBackFlag = 0;
		}
		
		if(GucKeyNum == KEY_SET)												/* 开始菜单下SET按键按下		 										*/
		{
			if(MODE==MODE_SV_SHOW)												/* 开始菜单显示与设置切换		 										*/
			{
				MODE = MODE_SV_SET;
				GucSvSetSelect=0;												/* 闪烁选择位					 										*/
			}
			else if(MODE==MODE_SV_SET)
			{
				PID_Save();														/* PID参数保存生效													    */
				MODE = MODE_SV_SHOW;											/* 返回主界面	   				 										*/
				SetSvNixieBuf(INDEX_SV_MENU);									/* 设置SV显示数组值 			 										*/
				FLASH_WritePage(FLASH_LAST_PAGE, GusMainMenuBuf);				/* 将设置数据写入FLASH 			 										*/
			}
		}
		
		if(GsLongKeyState == 1)
		{
			GucSvSetSelect=0;
			if(MODE == ENG_MENU)
			{
				/* 写入FLASH保存 */
				FLASH_WritePage(FLASH_LAST_PAGE, GusMainMenuBuf);				/* 将设置数据写入FLASH								 	 				*/
				/*****************/
				SetSvNixieBuf(INDEX_SV_MENU);									/* 将主菜单缓存数组值写入SV显示缓存数组			    	 				*/
				MODE=MODE_SV_SHOW;												/* 返回开始界面											 				*/
			}
			else if(MODE == COD_MENU)
			{
				/* 写入FLASH保存 */
				FLASH_WritePage(FLASH_LAST_PAGE, GusMainMenuBuf);				/* 将设置数据写入FLASH								 	 				*/
				/*****************/
				SetSvNixieBuf(INDEX_SV_MENU);									/* 将主菜单缓存数组值写入SV显示缓存数组			    	 				*/
				MODE=MODE_SV_SHOW;												/* 返回开始界面											 				*/
			}
			else if(MODE == MODE_SV_SHOW)
			{
				SetSvNixieBuf(INDEX_COD);
				MODE = COD_MENU;
			}
		}
		else if(GsLongKeyState == 2)
		{
			if(GsPvShowmode == 0)
			{
				GsPvShowmode = 1;
			}
			else
			{
				GsPvShowmode = 0;
			}
		}
		else if(GsLongKeyState == 3)
		{
			if(PID_Auto_Deal == 0)
			{
				AT = 1;
				Nixie_SetBuf_forcase9(1, AT_S);
				PID_Auto_Deal = 1;
				PID_read = 0;
				PID_Auto_Time = 0;
				temp_high = -50;
				temp_low = 400;
			}
			else
			{
				AT = 0;
				Nixie_SetBuf_forcase9(0, ~AT_S);
				PID_Auto_Deal = 0;
				PID_read = 1;
				PID_Auto_Time = 0;
				temp_high = -50;
				temp_low = 400;
			}
		}
		switch(MODE)															/* 模式选择						 										*/
		{
			case MODE_SV_SHOW:
			{
				Nixie_Show(SV);													/* 开机主界面显示PV显示温度值，SV显示期望值       						*/
				if(GucPvSetADC_Flag == 1)
				{
					GusADC_Result = middleValueFilter();
					GsTemperature = (int16_t)temp_Sample(GusADC_Result);
//					GsTemperature = POINTVOTAGE;
					temperature_limiting();
					GusPvValue = (uint16_t)GsTemperature;
					GucPvSetADC_Flag = 0;
				}
				if(GucPvSetATU_Flag == 1)
				{
					pid.Pv = GsTemperature;
					PID_Auto();
					GucPvSetATU_Flag = 0;
				}
				if(GsPvShowmode == 0)
				{
					GusPvValue = (uint16_t)GsTemperature;
					Nixie_SetBuf_forcase9(1, CENTIGRADE);
					Nixie_SetBuf_forcase9(0, ~FANRENHEIT);
				}
				else if(GsPvShowmode == 1)
				{
					GusPvValue = Centigrade_to_Fahrenheit((int16_t)GsTemperature);
					Nixie_SetBuf_forcase9(1, FANRENHEIT);
					Nixie_SetBuf_forcase9(0, ~CENTIGRADE);
				}
				if(GusADC_Result != 4095)
				{
					GsTempError = 0;//错误标志位置0
					GcPvNixieBuf[0] = GusPvValue%10;
					GcPvNixieBuf[1] = GusPvValue/10%10;
					GcPvNixieBuf[2] = GusPvValue/100%10;
					GcPvNixieBuf[3] = GusPvValue/1000%10;
					Nixie_Show(PV);	
				}
				else															/* 热电偶未接入 */
				{
					pid.PID_OUT = 0;//不加热
					GsTempError = 1;//错误标志位置1
					Nixie_SetBuf(2, 28);
					Nixie_SetBuf(3, 28);
					Nixie_SetBuf(4, 28);
				}
																/* 开机主界面显示PV显示温度值，SV显示期望值       						*/
				break;
			}
			case MODE_SV_SET:
			{
				Nixie_SetBuf(1, 10);
				Nixie_SetBuf(2, 10);
				Nixie_SetBuf(3, 5);
				Nixie_SetBuf(4, 17);
				SV_Set_ForSV(INDEX_SV_MENU);									/* SV设置界面，选中位闪烁						  						*/
				break;
			}
			case MAIN_MENU:														/* 长按SET进入，长按处理key_handle()中    		  						*/
			{
				if(GucKeyNum == KEY_SET)
				{
					GucMainMenuIndex++;
					GucMainMenuIndex %= 12;
					if(PID_P != 0)
					{
						if(GucMainMenuIndex == INDEX_OH)
						{
							GucMainMenuIndex++; 
						}
					}
					else if(PID_P == 0)
					{
						if(GucMainMenuIndex == INDEX_I)
						{
							GucMainMenuIndex+=4; 
						}
					}
					GucSvSetSelect=0;
					SetSvNixieBuf(GucMainMenuIndex);							/* 在主菜单模式下按SET切换选项，将主菜单缓存数组写入显示数组			 */
				}
				Main_Menu_Handle(GucMainMenuIndex);								/* 主菜单处理函数          												 */
				break;
			}
			case COD_MENU:														/* COD选项（COD = 1进入工程师菜单，COD = 999系统复位），其他返回开始菜单 */
			{
				if(GucKeyNum == KEY_SET)
				{
					if(COD == 1)
					{
						MODE = ENG_MENU;										/* cod = 1进入工程师菜单选项 											 */
						GucMainMenuIndex = INDEX_SLL;							/* 菜单选项索引等于工程师菜单第一项										 */
						SetSvNixieBuf(GucMainMenuIndex);						/* 将菜单选项值写入显示缓存数组 										 */
						GucSvSetSelect=0;
						COD = 0;												/* COD清零																 */
					}
					else if(COD == 999)											/* COD = 999,系统复位，即所有参数恢复默认								 */
					{
						MenuFlash_Init();
						SetSvNixieBuf(INDEX_SV_MENU);							/* 将主菜单缓存数组值写入SV显示缓存数组，即在显示数组写入SV				 */
						MODE = MODE_SV_SHOW;									/* 返回开始界面	   														 */
						COD = 0;												/* COD清零																 */
						PID_Save();
					}
					else if(COD == 10)
					{
						POINTVOTAGE = ((float)middleValueFilter()/4095)*5*1000;			/* 零点电压校准 */
						FLASH_WritePage(FLASH_LAST_PAGE, GusMainMenuBuf);							/* 将设置数据写入FLASH			 	 					 */
//						delay_ms(5);
						SetSvNixieBuf(INDEX_SV_MENU);							/* 将主菜单缓存数组值写入SV显示缓存数组，即在显示数组写入SV				 */
						MODE = MODE_SV_SHOW;									/* 返回开始界面	   														 */
						COD = 0;												/* COD清零																 */
					}
					else
					{
						MODE = MODE_SV_SHOW;									/* 返回主界面													    	 */
						COD = 0;												/* COD清零																 */
						SetSvNixieBuf(INDEX_SV_MENU);							/* 将主菜单缓存数组值写入SV显示缓存数组，即在显示数组写入SV				 */
					}
				}
				Eng_Menu_Handle(INDEX_COD);										/* 工程师菜单处理函数，为节省代码篇幅，cod处理写在工程师菜单处理函数里	 */
				break;
			}
			case ENG_MENU:														/* 工程师菜单选项														 */
			{
				if(GucKeyNum == KEY_SET)
				{
					if(GucKeyNum == KEY_SET)
					{
						GucSvSetSelect=0;
						GucMainMenuIndex ++;
						if(GucMainMenuIndex >= 18)
						{
							GucMainMenuIndex = INDEX_SLL;						/* 循环显示工程师菜单选项												 */
						}
						SetSvNixieBuf(GucMainMenuIndex);						/* 将菜单选项值写入显示缓存数组											 */
					}
				}
				Eng_Menu_Handle(GucMainMenuIndex);								/* 工程师菜单处理函数													 */
				break;
			}
			default:{
				break;
			}
		}
		LED_Logic();
		if(GsTempError == 0)
		{
			if(PID_P != 0)
			{
				if(PID_Auto_Deal == 0/* && PID_Calculate_flag == 1*/)
				{
					PID_Calculate();
				}
			}
			else
			{
				if(GsTemperature < SV_MENU - OH)
				{
					Nixie_SetBuf_forcase9(1, OUT);
					PWM_OUT(1);
				}
				else if(GsTemperature >= SV_MENU + OH)
				{
					Nixie_SetBuf_forcase9(0, ~OUT);
					PWM_OUT(0);
				}
			}
		}
		
	}
}
